/*****************************************************************
 * Authors
 *	Khaled Mohammed (khaled.mohammed@gmail.com)
 *
 * TM4.java
 * this file implements a server which runs on TM4 host machine.
 * and a forward server which runs on an ugsparc machine.
 ****************************************************************/

package com.madinatek.designproject.server;

import java.io.*;
import java.net.*;
import com.madinatek.designproject.client.*;

public class TM4 {
	int port;
	boolean isMiddleServer;
	String forward_hostname;
	
	void run() {
		try {
			boolean isListening = true;
			ServerSocket serverSocket = new ServerSocket(port);

			while(isListening)
				new TM4HandlerThread(serverSocket.accept(), isMiddleServer, forward_hostname).start();	

			serverSocket.close();
		}
		catch(IOException e) {
			System.err.println(e.getMessage());
		}
	}

	public TM4 (int port, boolean isMiddleServer, String hostname) {
		this.port = port;
		this.isMiddleServer = isMiddleServer;
		forward_hostname = hostname;
	}

	public static void main(String [] args) {
		TM4 tm4;
		int port = 54035;
		boolean middleserver = false;
		String forward_hostname = "wildcat.eecg";

		for(int i=0; i < args.length; i++)
		{
			if(args[i].equalsIgnoreCase("--port")) {
				if(args.length < i + 2) {
					System.err.println("Usage: java TM4 --port 7890");
					return;
				}
				port = Integer.parseInt(args[++i]);
			}
			else if(args[i].equalsIgnoreCase("--server-forward")) {				
				middleserver = true;
				if(i+2 < args.length)
				forward_hostname = args[++i];
			}
		}
		
		System.out.println("Using port # " + port);		
		
		tm4 = new TM4(port, middleserver, forward_hostname); 
		tm4.run();
	}
}

class TM4HandlerThread extends Thread {
	private Socket socket = null;
	boolean isMiddleServer;
	String hostname;
	public TM4HandlerThread(Socket socket, boolean isMiddleServer, String hostname) {
		super("TM4HandlerThread");
		this.socket = socket;
		this.isMiddleServer = isMiddleServer;
		this.hostname = hostname;
	}

	public void run() {
		try {
			ObjectInputStream fromClient = new ObjectInputStream(socket.getInputStream());			

			TM4Packet packetFromClient = (TM4Packet) fromClient.readObject();
			TM4Packet packetToClient;
			System.out.println("Packet received: " + packetFromClient.FileName);
				
			if(isMiddleServer) {
				Socket forwardSock = new Socket(hostname, 54035);
				
				//FileTransfer.SendFile(hostname, "/nfs/ugsparcs/a-c/a-c/abdulka/dp/" + packetFromClient.FileName, "~/dp");
				
				ObjectOutputStream toServer = new ObjectOutputStream(forwardSock.getOutputStream());
				toServer.writeObject(packetFromClient);								
				
				System.err.println("MiddleServer >> Packet forwarded");
				
				ObjectInputStream fromServer = new ObjectInputStream(forwardSock.getInputStream());
				packetToClient = (TM4Packet) fromServer.readObject();
				
				System.err.println("MiddleServer >> Ack Received");
				
				toServer.close();
				fromServer.close();
				forwardSock.close();
			} else {
				File currentPath = new File(".");
				int index = packetFromClient.FileName.lastIndexOf(".tar");
				String cmds =  "/bin/sh " + currentPath.getCanonicalPath() + "start.sh ~/dp " + packetFromClient.FileName.replaceAll("\\r", "") + " " + packetFromClient.FileName.substring(0, index).trim(); 							
				System.out.println(cmds);
								
				Process p = Runtime.getRuntime().exec(cmds);
				/*
				BufferedReader br1 = new BufferedReader(new InputStreamReader(p.getInputStream()));
				
				System.err.println("\n\tPriting output");
				
				String line;
				while((line = br1.readLine()) != null) {
					System.err.println(line);	
				}
				
				System.err.println("\n\tPriting Error");
				
				BufferedReader br2 = new BufferedReader(new InputStreamReader(p.getErrorStream()));
				
				while((line = br2.readLine()) != null) {
					System.err.println(line);	
				}
				*/
				
				packetToClient = new TM4Packet();
				packetToClient.Type = TM4Packet.SERVER_ACK;
			}
			
			
			System.err.println("ACK Sent");
			ObjectOutputStream toClient = new ObjectOutputStream(socket.getOutputStream());
			toClient.writeObject(packetToClient);
			
			fromClient.close();
			toClient.close(); 			
			socket.close();
		}
		catch(Exception ex) {
			ex.printStackTrace();
			System.exit(-1);
		}
	}
}
